home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
3_0
/
COPYFILE
/
COPY.C
next >
Wrap
C/C++ Source or Header
|
1989-05-17
|
5KB
|
217 lines
/*
Copy -- copies one file to another
Instructions for XCMDs are in <XCMD.HowToUse>
*/
#include <HyperXCmd.h>
#include <SetUpA4.h>
/* Constants */
#define NULL 0L
#define FALSE 0
#define TRUE 1
#define BLOCK_SIZE 512
/* Macros */
#define strlen(s) StringLength(paramPtr, (StringPtr) (s))
#define pasToZero(s) PasToZero(paramPtr, (StringPtr) (s))
#define zeroToPas(s1,s2) ZeroToPas(paramPtr, (char *) (s1), \
(StringPtr) (s2))
#define numToStr(l,s) NumToStr(paramPtr, (long) (l), s)
/* Static variables */
static char sWrongArgs[] = "\pWrong number of arguments";
/* Prototypes */
pascal void main(XCmdBlockPtr);
int CopyFile(char *, char *);
int CopyBytes(IOParam *io1, IOParam *io2, long bytes);
pascal void main(paramPtr)
XCmdBlockPtr paramPtr;
{
int err;
Str31 str;
Str255 source, dest;
RememberA0();
SetUpA4();
if (paramPtr->paramCount != 2)
paramPtr->returnValue = pasToZero(sWrongArgs);
else {
zeroToPas(*paramPtr->params[0], source);
zeroToPas(*paramPtr->params[1], dest);
err = CopyFile((char *) source, (char *) dest);
if (err) {
numToStr(err, &str);
paramPtr->returnValue = pasToZero(str.guts);
}
}
RestoreA4();
}
int CopyFile(source, dest)
char *source, *dest;
{
/* <FileMgr.h>*/
FileParam fp1, fp2;
int err;
IOParam io1, io2;
/* Start by getting info about the source file */
fp1.ioCompletion = NULL;
fp1.ioNamePtr = (StringPtr) source;
fp1.ioVRefNum = 0;
fp1.ioFVersNum = 0;
fp1.ioFDirIndex = 0;
err = PBGetFInfo(&fp1, FALSE);
if (err != noErr) {SysBeep(3);
return (err);}
/* Next create the dest file */
fp2.ioCompletion = NULL;
fp2.ioNamePtr = (StringPtr) dest;
fp2.ioVRefNum = 0;
fp2.ioFVersNum = 0;
err = PBCreate(&fp2, FALSE);
if (err == dupFNErr) {
/* File already existed -- wipe it out */
err = PBDelete(&fp2, FALSE);
if (err != noErr)
return (err);
err = PBCreate(&fp2, FALSE);
if (err != noErr)
return (err);
}
else if (err != noErr)
return (err);
/* Set the file info on the new file */
fp2.ioFlFndrInfo = fp1.ioFlFndrInfo;
fp2.ioFlFndrInfo.fdFlags = 0;
fp2.ioFlCrDat = fp1.ioFlCrDat;
fp2.ioFlMdDat = fp1.ioFlMdDat;
err = PBSetFInfo(&fp2, FALSE);
/* Fill in the I/O params */
io1.ioCompletion = NULL;
io1.ioNamePtr = (StringPtr) source;
io1.ioVRefNum = 0;
io1.ioVersNum = 0;
io1.ioPermssn = fsRdPerm;
io1.ioMisc = NULL;
io2.ioCompletion = NULL;
io2.ioNamePtr = (StringPtr) dest;
io2.ioVRefNum = 0;
io2.ioVersNum = 0;
io2.ioPermssn = fsWrPerm;
io2.ioMisc = NULL;
/* Now, copy the files' data forks (if they exist) */
if (fp1.ioFlLgLen > 0L) {
/* Start with the destination */
err = PBOpen(&io2, FALSE);
if (err != noErr)
return (err);
/* Allocate space to copy to */
io2.ioReqCount = fp1.ioFlLgLen;
err = PBAllocate(&io2, FALSE);
if (err != noErr) {
PBClose(&io2, FALSE);
return (err);
}
err = PBOpen(&io1, FALSE);
if (err != noErr) {
PBClose(&io2, FALSE);
return (err);
}
err = CopyBytes(&io1, &io2, fp1.ioFlLgLen);
PBClose(&io1, FALSE);
PBClose(&io2, FALSE);
if (err != noErr)
return (err);
}
/* Copy the files' resource forks (if they exist) */
if (fp1.ioFlRLgLen > 0L) {
/* Start with the destination */
err = PBOpenRF(&io2, FALSE);
if (err != noErr)
return (err);
/* Allocate space to copy to */
io2.ioReqCount = fp1.ioFlRLgLen;
err = PBAllocate(&io2, FALSE);
if (err != noErr) {
PBClose(&io2, FALSE);
return (err);
}
err = PBOpenRF(&io1, FALSE);
if (err != noErr) {
PBClose(&io2, FALSE);
return (err);
}
err = CopyBytes(&io1, &io2, fp1.ioFlRLgLen);
PBClose(&io1, FALSE);
PBClose(&io2, FALSE);
if (err != noErr)
return (err);
}
return (err);
}
int CopyBytes(io1, io2, bytes)
IOParam *io1, *io2;
long bytes;
{
char buffer[BLOCK_SIZE];
long numFullBlocks, i;
int err;
numFullBlocks = bytes / BLOCK_SIZE;
/* Fill in the missing parts of the I/O params */
io1->ioBuffer = buffer;
io1->ioReqCount = BLOCK_SIZE;
io1->ioPosMode = fsFromStart;
io1->ioPosOffset = 0L;
io2->ioBuffer = buffer;
io2->ioReqCount = BLOCK_SIZE;
io2->ioPosMode = fsFromStart;
io2->ioPosOffset = 0L;
/* Note: the following loop copies the number of full blocks.
There may be a partial last block. */
for (i = 0; i < numFullBlocks; i++) {
err = PBRead(io1, FALSE);
if (err != noErr)
return (err);
err = PBWrite(io2, FALSE);
if (err != noErr)
return (err);
}
/* Copy the last amount */
io1->ioReqCount = io2->ioReqCount = bytes % BLOCK_SIZE;
if (io1->ioReqCount != 0L) {
err = PBRead(io1, FALSE);
if (err != noErr)
return (err);
err = PBWrite(io2, FALSE);
if (err != noErr)
return (err);
}
return (noErr);
}
/* C routines for HyperCard callbacks */
#include <XCmdGlue.inc.c>